#include "tim3.h"

static u32 counter;
static u32 wait;
static TIMCallBack CallBackFun;

void tim3_init(void)
{
    /*开启外设时钟*/
    RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM3, ENABLE); 
    /*设置tim2时钟来源为内部时钟*/
    TIM_InternalClockConfig(TIM3);

    /*配置时基单元*/
    TIM_TimeBaseInitTypeDef TIM3_InitStruct;
    TIM3_InitStruct.TIM_ClockDivision = TIM_CKD_DIV1;  //时钟源分频,这里选1分频
    TIM3_InitStruct.TIM_CounterMode	= TIM_CounterMode_Up;//计数器模式 这里选择向上计数 (此外还有向下计数, 中央对齐计数等)
    TIM3_InitStruct.TIM_RepetitionCounter = 0;//重复计数器的值 高级定时器才有, 这里用不上直接给零
    /*设置定时器周期 20ms*/
    TIM3_InitStruct.TIM_Prescaler = 72 - 1;	//PSC预分频器的值
    TIM3_InitStruct.TIM_Period = 20000 - 1; 	//周期 即ARR自动重装器的值
    TIM_TimeBaseInit(TIM3, &TIM3_InitStruct); //初始化配置函数

    /*清除复位时产生的一次更新中断*/
    TIM_ClearFlag(TIM3, TIM_FLAG_Update);

    /*中断配置*/
    TIM_ITConfig(TIM3, TIM_IT_Update, ENABLE); //使能更新中断 TIM_ITConfig()

    NVIC_InitTypeDef NVIC_InitStruct;
    NVIC_InitStruct.NVIC_IRQChannel = TIM3_IRQn; //指定中断通道开启/关闭  这里选择 TIM3号中断通道 对应 TIM3
    NVIC_InitStruct.NVIC_IRQChannelCmd = ENABLE; //指定中断通道使能/失能		
    NVIC_InitStruct.NVIC_IRQChannelPreemptionPriority = 4;	//指定所选通道的抢占优先级
    NVIC_InitStruct.NVIC_IRQChannelSubPriority = 0; //指定所选通道的响应优先级
    NVIC_Init(&NVIC_InitStruct); //初始化

    TIM_Cmd(TIM3, DISABLE); 
}

/// @brief 注册回调函数, 并在第t个时钟周期后调用, T = 20ms
/// @param fun 需要调用的回调函数, 在中断中运行, 所以请尽量简短
/// @param t 表示要在几个时钟周期调用函数
void tim3_setCallBack(TIMCallBack fun, u16 t)
{
    counter = 0;
    wait = t;
    CallBackFun = fun;
    
    TIM_ITConfig(TIM3, TIM_IT_Update, ENABLE); //使能更新中断 TIM_ITConfig()
    /*启动计时器*/
    TIM_Cmd(TIM3, ENABLE); 
    
}

//TIM2 中断函数
void TIM3_IRQHandler(void)
{
    //检查中断标志位 这里检查TIM3计时器的更新中断位
	if ( TIM_GetITStatus(TIM3, TIM_IT_Update) == SET )
	{
        if(counter == wait)
        {
            TIM_ITConfig(TIM3, TIM_IT_Update, DISABLE); //使能更新中断 TIM_ITConfig()
            TIM_Cmd(TIM3, DISABLE); 
            counter = 0;
            wait = 0;
            CallBackFun();
        }
        counter += 1;
		//清理标志位
		TIM_ClearITPendingBit(TIM3, TIM_IT_Update);
	}
}